package com.hiss.basic.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.hiss.basic.client.system.ISysParameterService;
import com.hiss.basic.model.system.domain.SysParameterDomain;
import com.hiss.basic.model.system.request.SysParameterCreateRequest;
import com.hiss.basic.model.system.request.SysParameterQueryRequest;
import com.hiss.basic.model.system.request.SysParameterUpdateRequest;
import com.hiss.basic.model.system.response.SysParameterQueryResponse;
import com.hiss.basic.starter.cache.annotation.CacheExpire;
import com.hiss.basic.starter.cache.constant.CacheConstant;
import com.hiss.basic.starter.core.enums.EnableStatusEnum;
import com.hiss.basic.starter.core.exception.BusinessException;
import com.hiss.basic.starter.core.helper.MapstructHelper;
import com.hiss.basic.starter.core.helper.ValidationHelper;
import com.hiss.basic.starter.mybatis.utils.PageUtils;
import com.hiss.basic.system.mapper.SysParameterMapper;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
 * 系统参数 service impl
 */
@Slf4j
@Service
@CacheConfig(cacheNames = CacheConstant.SYS_PARAMETER_KEY)
public class SysParameterServiceImpl extends ServiceImpl<SysParameterMapper, SysParameterDomain> implements ISysParameterService {

    @Override
    public Page<SysParameterQueryResponse> findPageList(SysParameterQueryRequest request) {
        QueryWrapper wrapper = new QueryWrapper();
        if (ObjectUtil.isNotNull(request)) {
            wrapper.like(SysParameterDomain::getName, request.getName(), StrUtil.isNotBlank(request.getName()));
            wrapper.like(SysParameterDomain::getKey, request.getKey(), StrUtil.isNotBlank(request.getKey()));
            wrapper.eq(SysParameterDomain::getEnableStatus, request.getEnableStatus(), ObjectUtil.isNotNull(request.getEnableStatus()));
        }
        wrapper.orderBy(SysParameterDomain::getCreateTime, false);
        Page page = PageUtils.getPage();
        return pageAs(page, wrapper, SysParameterQueryResponse.class);
    }

    @Override
    @CacheExpire(60 * 60 * 3)
    @Cacheable(key = "#key", unless = "#result == null")
    public SysParameterQueryResponse findByKey(String key) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq(SysParameterDomain::getKey, key);
        wrapper.eq(SysParameterDomain::getEnableStatus, EnableStatusEnum.ENABLE.getCode());
        wrapper.limit(1);
        return getOneAs(wrapper, SysParameterQueryResponse.class);
    }

    @Override
    @CacheEvict(allEntries = true)
    public void create(SysParameterCreateRequest request) {
        ValidationHelper.validate(request);

        long count = QueryChain.of(SysParameterDomain.class).eq(SysParameterDomain::getKey, request.getKey()).count();
        if (count > 0) {
            throw new BusinessException("参数键名已存在");
        }

        SysParameterDomain domain = MapstructHelper.convert(request, SysParameterDomain.class);
        save(domain);
    }

    @Override
    @CacheEvict(allEntries = true)
    public void update(SysParameterUpdateRequest request) {
        ValidationHelper.validate(request);

        long count = QueryChain.of(SysParameterDomain.class)
                .eq(SysParameterDomain::getKey, request.getKey())
                .ne(SysParameterDomain::getId, request.getId())
                .count();
        if (count > 0) {
            throw new BusinessException("参数键名已存在");
        }

        SysParameterDomain domain = MapstructHelper.convert(request, SysParameterDomain.class);
        updateById(domain);
    }

    @Override
    @CacheEvict(allEntries = true)
    public void remove(Long id) {
        removeById(id);
    }
}
